use std::collections::HashMap;
use std::fs;
use std::sync::RwLock;

use attestation_common::log::{error, info};

use crate::policy_error::policy_error::PolicyError;
use crate::util::policy_util::PolicyUtil;

pub struct ExportPolicyHandler;

impl ExportPolicyHandler {

    pub fn get_policy_from_cache(attester_type: &str, cache_lock: &RwLock<HashMap<String, String>>) -> Result<Option<String>, PolicyError> {
        let cache = cache_lock.read().map_err(|e| {
            error!("Failed to acquire read lock on export policy cache: {}", e);
            PolicyError::InternalError(format!("Failed to acquire read lock: {}", e))
        })?;
        
        if let Some(content) = cache.get(attester_type) {
            info!("Found cached export policy for attester_type: {}", attester_type);
            return Ok(Some(content.clone()));
        }
        
        Ok(None)
    }

    pub fn get_policy_file_path(attester_type: &str) -> Result<String, PolicyError> {
        match PolicyUtil::get_map_yaml_config("attestation_service.policy.export_policy_file", "".to_string(), attester_type) {
            Ok(value) => Ok(value),
            Err(e) => {
                error!("Failed to get export policy file configuration: {}", e);
                Err(PolicyError::InternalError(format!("Failed to get configuration: {}", e)))
            }
        }
    }

    pub fn read_policy_file(policy_file_path: &str) -> Result<String, PolicyError> {
        match fs::read_to_string(policy_file_path) {
            Ok(content) => Ok(content),
            Err(e) => {
                error!("Failed to read policy file {}: {}", policy_file_path, e);
                Err(PolicyError::PolicyNotFoundError(format!("Failed to read policy file: {}", e)))
            }
        }
    }

    pub fn cache_policy(attester_type: &str, content: String, cache_lock: &RwLock<HashMap<String, String>>) -> Result<(), PolicyError> {
        let mut cache = cache_lock.write().map_err(|e| {
            error!("Failed to acquire write lock on export policy cache: {}", e);
            PolicyError::InternalError(format!("Failed to acquire write lock: {}", e))
        })?;
        
        cache.insert(attester_type.to_string(), content);
        info!("Cached export policy for attester_type: {}", attester_type);
        Ok(())
    }
}